/**
 * Copyright (C) 2022-2023
 * All rights reserved, Designed By www.tonetn.com
 * 注意：
 * 本软件为www.tonetn.com开发研制，未经购买不得使用
 * 购买后可获得全部源代码（禁止转卖、分享、上传到码云、github等开源平台）
 * 一经发现盗用、分享等行为，将追究法律责任，后果自负
 */
package com.xunyin.modules.mp.service;

import cn.hutool.core.util.StrUtil;
import com.xunyin.api.XunyinException;
import com.xunyin.constant.ShopConstants;
import com.xunyin.enums.ShopCommonEnum;
import com.xunyin.modules.mp.config.WxMpConfiguration;
import com.xunyin.modules.mp.domain.YxWechatTemplate;
import com.xunyin.modules.mp.enums.WechatTempateEnum;
import com.xunyin.modules.mtstore.service.mapper.MtStaffMapper;
import com.xunyin.modules.user.domain.YxUser;
import com.xunyin.modules.user.service.YxUserService;
import com.xunyin.modules.user.service.dto.WechatUserDto;
import com.xunyin.utils.RedisUtil;
import com.xunyin.utils.RedisUtils;
import com.xunyin.utils.ShopKeyUtils;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.template.WxMpTemplateData;
import me.chanjar.weixin.mp.bean.template.WxMpTemplateMessage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @ClassName 微信公众号模板通知
 * @Author xunyinyunshang  <3594419785@qq.com>
 * @Date 2020/6/27
 **/
@Slf4j
@Service
public class WeixinTemplateService {

    @Autowired
    private RedisUtils redisUtils;

    @Autowired
    private YxUserService userService;
    @Autowired
    private YxWechatTemplateService yxWechatTemplateService;

    @Autowired
    private MtStaffMapper mtStaffMapper;

    /**
     * 取消订单给保洁员通知
     * 详细内容
     * 房间名称{{thing11.DATA}}
     * 联系电话{{phone_number15.DATA}}
     * 取消时间{{time18.DATA}}
     * 开始时间{{time12.DATA}}
     * 结束时间{{time13.DATA}}
     */
    public void orderCancelSuccessNotice(Date teaServerStartTime, Date teaServerEndTime, Date updateTime,
                                         String storeRoomName,String userPhone, String openId){

        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
        Map<String, String> map = new HashMap<>();
        map.put("thing11", "预约-"+storeRoomName);
        map.put("phone_number15", userPhone);
        map.put("time18", simpleDateFormat.format(updateTime));
        map.put("time12", simpleDateFormat.format(teaServerStartTime));
        map.put("time13", simpleDateFormat.format(teaServerEndTime));
        String tempId = this.getTempId(WechatTempateEnum.GZH_ORDER_CANCEL_SUCCESS.getValue());
        log.info("tempId:"+tempId);
        log.info("openId:"+openId);
        this.sendWxMpTemplateMessage(openId, tempId, this.getSiteUrl() + "pages/userPage/index", map);
    }

    /**
     * 新订单提醒给保洁员通知
     *
     房间名称
     {{thing11.DATA}}
     订单金额
     {{amount3.DATA}}
     客户电话
     {{phone_number8.DATA}}
     下单时间
     {{time13.DATA}}
     结束时间
     {{time12.DATA}}
     */
    public void orderNewSuccessNotice(Date teaServerStartTime, Date teaServerEndTime,
                                      String orderNo,String storeRoomName,
                                      String storeName, Integer storeId,
                                      BigDecimal orderMondey,
                                      String userPhone, String openId) {
        // 根据门店id,查询保洁员对应
/*        LambdaQueryWrapper<MtStaff> lambdaQueryWrapper = Wrappers.lambdaQuery();
        lambdaQueryWrapper.eq(MtStaff::getStoreId, storeId);
        lambdaQueryWrapper.eq(MtStaff::getCategory, 2);
        List<MtStaff> dataList = mtStaffMapper.selectList(lambdaQueryWrapper);
        for (MtStaff mtStaff : dataList) {
            YxUser yxUser = userService.queryYxUserByMobile(mtStaff.getMobile());
            String openid = this.getUserOpenid(yxUser.getUid());
            if (StrUtil.isBlank(openid)) {
                return;
            }*/
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
            Map<String, String> map = new HashMap<>();

/*            map.put("first", "下单成功通知");
            map.put("keyword1", "预约-"+storeRoomName);
            map.put("keyword2", orderNo);
            map.put("keyword3", "购买人："+userPhone);
            map.put("keyword4", orderMondey+"");
            map.put("keyword5", "预约时间范围："+simpleDateFormat.format(teaServerStartTime)+"~"+simpleDateFormat.format(teaServerEndTime));
            map.put("remark", ShopConstants.YSHOP_WECHAT_PUSH_REMARK);*/

            map.put("thing11", "预约-"+storeRoomName);
            map.put("amount3", orderMondey+"");
            map.put("phone_number8", userPhone);
            map.put("time13", simpleDateFormat.format(teaServerStartTime));
            map.put("time12", simpleDateFormat.format(teaServerEndTime));

/*            map.put("thing14", "预约-"+storeRoomName);
            map.put("amount7", orderMondey+"");
            map.put("phone_number23", userPhone);
            map.put("date10", simpleDateFormat.format(teaServerStartTime));
            map.put("time15", simpleDateFormat.format(teaServerEndTime));*/

            String tempId = this.getTempId(WechatTempateEnum.GZH_ORDER_NEW_SUCCESS.getValue());
            log.info("tempId:"+tempId);
            log.info("openId:"+openId);
            this.sendWxMpTemplateMessage(openId, tempId, this.getSiteUrl() + "pages/userPage/index", map);

/*            String appId = RedisUtil.get(ShopKeyUtils.getWxAppAppId());
            if (StrUtil.isNotBlank(tempId)) {
                if (StrUtil.isBlank(appId)) {
                    this.sendWxMpTemplateMessage(openId, tempId, this.getSiteUrl() + "pages/userPage/index", map);
                } else {
                    WxMpTemplateMessage.MiniProgram miniProgram = new WxMpTemplateMessage.MiniProgram();
                    miniProgram.setAppid(RedisUtil.get(ShopKeyUtils.getWxAppAppId()));
                    miniProgram.setPagePath("pages/userPage/index");
                    //miniProgram.setPagePath("pages/orderAdmin/AdminOrder/index?oid=" + orderId);
                    this.sendWxMpTemplateMessageToWx(openId, tempId, miniProgram, map);
                }
            }*/

        //}
    }

    /**
     * 订单结束提醒给保洁员通知
     门店名称
     {{thing2.DATA}}
     完成时间
     {{time18.DATA}}
     * @param orderNo          订单号
     * @param teaServerEndTime 订单结束时间
     * @param storeRoomName    房间名称
     * @param storeName        门店名称
     * @param storeId          门店Id
     */
    public void orderEndNotice(String orderNo, Date teaServerEndTime, String storeRoomName, String storeName, Integer storeId,String openId) {

        // 根据门店id,查询保洁员对应
/*        LambdaQueryWrapper<MtStaff> lambdaQueryWrapper = Wrappers.lambdaQuery();
        lambdaQueryWrapper.eq(MtStaff::getStoreId, storeId);
        lambdaQueryWrapper.eq(MtStaff::getCategory, 2);
        List<MtStaff> dataList = mtStaffMapper.selectList(lambdaQueryWrapper);
        for (MtStaff mtStaff : dataList) {

            YxUser yxUser = userService.queryYxUserByMobile(mtStaff.getMobile());
            String openid = this.getUserOpenid(yxUser.getUid());
            if (StrUtil.isBlank(openid)) {
                return;
            }*/

            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
            Map<String, String> map = new HashMap<>();

/*          map.put("first", "订单结束通知");
            map.put("keyword1", orderNo);
            map.put("keyword2", "待清洁");
            map.put("keyword3", "订单结束时间:"+simpleDateFormat.format(teaServerEndTime));
            map.put("keyword4", storeName+"-"+storeRoomName);
            map.put("remark", ShopConstants.REMARK_WECHAT_PUSH_REMARK);*/

            map.put("thing2", storeRoomName);
            map.put("time18", simpleDateFormat.format(teaServerEndTime));

/*            门店名称
            {{thing22.DATA}}

            完成时间
            {{time16.DATA}}*/

/*            map.put("thing22", storeRoomName);
            map.put("time16", simpleDateFormat.format(teaServerEndTime));*/

            String tempId = this.getTempId(WechatTempateEnum.GZH_ORDER_END.getValue());
            this.sendWxMpTemplateMessage(openId, tempId, this.getSiteUrl() + "/pages/userPage/index", map);

/*            String appId = RedisUtil.get(ShopKeyUtils.getWxAppAppId());
            if (StrUtil.isNotBlank(tempId)) {
                if (StrUtil.isBlank(appId)) {
                    this.sendWxMpTemplateMessage(openId, tempId, this.getSiteUrl() + "/pages/userPage/index", map);
                } else {
                    WxMpTemplateMessage.MiniProgram miniProgram = new WxMpTemplateMessage.MiniProgram();
                    miniProgram.setAppid(RedisUtil.get(ShopKeyUtils.getWxAppAppId()));
                    miniProgram.setPagePath("pages/userPage/index");
                    //miniProgram.setPagePath("pages/orderAdmin/AdminOrder/index?oid=" + orderId);
                    this.sendWxMpTemplateMessageToWx(openId, tempId, miniProgram, map);
                }
            }*/

/*            if (StrUtil.isNotBlank(tempId)) {
                this.sendWxMpTemplateMessage(openid, tempId, this.getSiteUrl() + "/pages/userPage/index", map);
            }*/
        //}
    }

    /**
     * 用户充值成功通知
     * 充值门店
     * {{thing10.DATA}}
     * 充值金额
     * {{amount2.DATA}}
     * 赠送金额
     * {{amount17.DATA}}
     * 充值时间
     * {{time4.DATA}}
     * @param storeName
     * @param rechargeAmount
     * @param giveAmount
     * @param rechargeTime
     */
    public void doRechargeSuccessNotice( Integer storeId,String storeName,BigDecimal rechargeAmount,
                                         BigDecimal giveAmount,Date rechargeTime,String openId){
        // 根据门店id,查询保洁员对应
/*        LambdaQueryWrapper<MtStaff> lambdaQueryWrapper = Wrappers.lambdaQuery();
        lambdaQueryWrapper.eq(MtStaff::getStoreId, storeId);
        lambdaQueryWrapper.eq(MtStaff::getCategory, 1);
        List<MtStaff> dataList = mtStaffMapper.selectList(lambdaQueryWrapper);
        for (MtStaff mtStaff : dataList) {

            YxUser yxUser = userService.queryYxUserByMobile(mtStaff.getMobile());
            String openid = this.getUserOpenid(yxUser.getUid());
            if (StrUtil.isBlank(openid)) {
                return;
            }*/

            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
            Map<String, String> map = new HashMap<>();

            map.put("thing10", storeName);
            map.put("amount2", rechargeAmount+"");
            map.put("amount17", giveAmount+"");
            map.put("time4", simpleDateFormat.format(rechargeTime));

            String tempId = this.getTempId(WechatTempateEnum.GZH_RECHARGE_SUCCESS.getValue());
            this.sendWxMpTemplateMessage(openId, tempId, this.getSiteUrl() + "/pages/userPage/index", map);

/*            String appId = RedisUtil.get(ShopKeyUtils.getWxAppAppId());
            if (StrUtil.isNotBlank(tempId)) {
                if (StrUtil.isBlank(appId)) {
                    this.sendWxMpTemplateMessage(openId, tempId, this.getSiteUrl() + "/pages/userPage/index", map);
                } else {
                    WxMpTemplateMessage.MiniProgram miniProgram = new WxMpTemplateMessage.MiniProgram();
                    miniProgram.setAppid(RedisUtil.get(ShopKeyUtils.getWxAppAppId()));
                    miniProgram.setPagePath("pages/userPage/index");
                    //miniProgram.setPagePath("pages/orderAdmin/AdminOrder/index?oid=" + orderId);
                    this.sendWxMpTemplateMessageToWx(openId, tempId, miniProgram, map);
                }
            }*/

/*            if (StrUtil.isNotBlank(tempId)) {
                this.sendWxMpTemplateMessage(openid, tempId, this.getSiteUrl() + "/pages/userPage/index", map);
            }*/



        //}
    }


    /**
     * 充值成功通知
     *
     * @param time  时间
     * @param price 金额
     * @param uid   uid
     */
    public void rechargeSuccessNotice(String time, String price, Long uid) {
        String openid = this.getUserOpenid(uid);

        if (StrUtil.isBlank(openid)) {
            return;
        }
        Map<String, String> map = new HashMap<>();

        map.put("first", "您的账户金币发生变动，详情如下：");
        map.put("keyword1", "充值");
        map.put("keyword2", time);
        map.put("keyword3", price);
        map.put("remark", ShopConstants.YSHOP_WECHAT_PUSH_REMARK);

        String tempId = this.getTempId(WechatTempateEnum.RECHARGE_SUCCESS.getValue());
        if (StrUtil.isNotBlank(tempId)) {
            this.sendWxMpTemplateMessage(openid, tempId, this.getSiteUrl() + "/user/account", map);
        }
    }


    /**
     * 支付成功通知
     *
     * @param orderId 订单号
     * @param price   金额
     * @param uid     uid
     */
    public void paySuccessNotice(String orderId, String price, Long uid) {

        String openid = this.getUserOpenid(uid);

        if (StrUtil.isBlank(openid)) {
            return;
        }

        Map<String, String> map = new HashMap<>();
        map.put("first", "您的订单已支付成功，我们会尽快为您发货。");
        //订单号
        map.put("keyword1", orderId);
        map.put("keyword2", price);
        map.put("remark", ShopConstants.YSHOP_WECHAT_PUSH_REMARK);
        String tempId = this.getTempId(WechatTempateEnum.PAY_SUCCESS.getValue());
        if (StrUtil.isNotBlank(tempId)) {
            this.sendWxMpTemplateMessage(openid, tempId, this.getSiteUrl() + "/order/detail/" + orderId, map);
        }
    }


    /**
     * 支付成功通知给客服
     *
     * @param orderId
     * @param price
     * @param openId
     */
    public void paySuccessNoticeToKefu(String orderId, String price, String openId) {
        Map<String, String> map = new HashMap<>();
        map.put("first", "尊敬的客服,您有新订单了");
        map.put("keyword1", orderId);
        map.put("keyword2", price);
        map.put("remark", ShopConstants.YSHOP_WECHAT_PUSH_REMARK);
        String tempId = this.getTempId(WechatTempateEnum.PAY_SUCCESS.getValue());
        String appId = RedisUtil.get(ShopKeyUtils.getWxAppAppId());
        if (StrUtil.isNotBlank(tempId)) {
            if (StrUtil.isBlank(appId)) {
                this.sendWxMpTemplateMessage(openId, tempId, this.getSiteUrl() + "/order/detail/" + orderId, map);
            } else {
                WxMpTemplateMessage.MiniProgram miniProgram = new WxMpTemplateMessage.MiniProgram();
                miniProgram.setAppid(RedisUtil.get(ShopKeyUtils.getWxAppAppId()));
                miniProgram.setPagePath("pages/orderAdmin/AdminOrder/index?oid=" + orderId);
                this.sendWxMpTemplateMessageToWx(openId, tempId, miniProgram, map);
            }
        }


    }


    /**
     * 退款成功通知
     *
     * @param orderId 订单号
     * @param price   金额
     * @param uid     uid
     * @param time    时间
     */
    public void refundSuccessNotice(String title, String orderId, String price, Long uid, String time) {

        String openid = this.getUserOpenid(uid);

        if (StrUtil.isBlank(openid)) {
            return;
        }

        Map<String, String> map = new HashMap<>();
        map.put("first", title);
        //订单号
        map.put("keyword1", orderId);
        map.put("keyword2", price);
        map.put("keyword3", time);
        map.put("remark", ShopConstants.YSHOP_WECHAT_PUSH_REMARK);
        String tempId = this.getTempId(WechatTempateEnum.REFUND_SUCCESS.getValue());
        if (StrUtil.isNotBlank(tempId)) {
            this.sendWxMpTemplateMessage(openid, tempId, this.getSiteUrl() + "/order/detail/" + orderId, map);
        }
    }

    /**
     * 发送退款申请给客服
     *
     * @param orderId 订单号
     * @param price   金额
     * @param openId  openId
     * @param time    时间
     */
    public void refundSuccessNoticeToKefu(String title, String orderId, String price, String openId, String time) {

        Map<String, String> map = new HashMap<>();
        map.put("first", title);
        //订单号
        map.put("keyword1", orderId);
        map.put("keyword2", price);
        map.put("keyword3", time);
        map.put("remark", ShopConstants.YSHOP_WECHAT_PUSH_REMARK);
        String tempId = this.getTempId(WechatTempateEnum.REFUND_SUCCESS.getValue());
        String appId = RedisUtil.get(ShopKeyUtils.getWxAppAppId());
        if (StrUtil.isNotBlank(tempId)) {
            if (StrUtil.isBlank(appId)) {
                this.sendWxMpTemplateMessage(openId, tempId, this.getSiteUrl() + "/order/detail/" + orderId, map);
            } else {
                WxMpTemplateMessage.MiniProgram miniProgram = new WxMpTemplateMessage.MiniProgram();
                miniProgram.setAppid(RedisUtil.get(ShopKeyUtils.getWxAppAppId()));
                miniProgram.setPagePath("pages/orderAdmin/AdminOrder/index?oid=" + orderId);
                this.sendWxMpTemplateMessageToWx(openId, tempId, miniProgram, map);
            }
        }
    }

    /**
     * 发货成功通知
     *
     * @param orderId      单号
     * @param deliveryName 快递公司
     * @param deliveryId   快递单号
     * @param uid          uid
     */
    public void deliverySuccessNotice(String orderId, String deliveryName,
                                      String deliveryId, Long uid) {

        String openid = this.getUserOpenid(uid);

        if (StrUtil.isEmpty(openid)) {
            return;
        }

        Map<String, String> map = new HashMap<>();
        map.put("first", "亲，宝贝已经启程了，好想快点来到你身边。");
        map.put("keyword2", deliveryName);
        map.put("keyword1", orderId);
        map.put("keyword3", deliveryId);
        map.put("remark", ShopConstants.YSHOP_WECHAT_PUSH_REMARK);
        String tempId = this.getTempId(WechatTempateEnum.DELIVERY_SUCCESS.getValue());
        if (StrUtil.isNotBlank(tempId)) {
            this.sendWxMpTemplateMessage(openid, tempId, this.getSiteUrl() + "/order/detail/" + orderId, map);
        }
    }


    /**
     * 构建微信模板通知
     *
     * @param openId     单号
     * @param templateId 模板id
     * @param url        跳转url
     * @param map        map内容
     * @return String
     */
    private String sendWxMpTemplateMessage(String openId, String templateId, String url, Map<String, String> map) {
        WxMpTemplateMessage templateMessage = WxMpTemplateMessage.builder()
                .toUser(openId)
                .templateId(templateId)
                .url(url)
                .build();
        map.forEach((k, v) -> {
            templateMessage.addData(new WxMpTemplateData(k, v, "#000000"));
        });
        String msgId = null;
        WxMpService wxService = WxMpConfiguration.getWxMpService();
        try {
            msgId = wxService.getTemplateMsgService().sendTemplateMsg(templateMessage);
            log.info("msgId:"+msgId);
        } catch (WxErrorException e) {
            e.printStackTrace();
        }
        return msgId;
    }


    public String sendWxMpTemplateMessageToWx(String openId, String templateId, WxMpTemplateMessage.MiniProgram miniProgram, Map<String, String> map) {
        WxMpTemplateMessage templateMessage = WxMpTemplateMessage.builder()
                .toUser(openId)
                .templateId(templateId)
                .miniProgram(miniProgram)
                .build();
        map.forEach((k, v) -> {
            templateMessage.addData(new WxMpTemplateData(k, v, "#000000"));
        });
        String msgId = null;
        WxMpService wxService = WxMpConfiguration.getWxMpService();
        try {
            msgId = wxService.getTemplateMsgService().sendTemplateMsg(templateMessage);
        } catch (WxErrorException e) {
            log.error(e.getMessage(), e);
        }
        return msgId;
    }


    /**
     * 获取模板消息id
     *
     * @param key 模板key
     * @return string
     */
    private String getTempId(String key) {
        YxWechatTemplate yxWechatTemplate = yxWechatTemplateService.lambdaQuery()
                .eq(YxWechatTemplate::getType, "template")
                .eq(YxWechatTemplate::getTempkey, key)
                .one();
        if (yxWechatTemplate == null) {
            throw new XunyinException("请后台配置key:" + key + "模板消息id");
        }

        if (ShopCommonEnum.IS_STATUS_0.getValue().equals(yxWechatTemplate.getStatus())) {
            return "";
        }

        return yxWechatTemplate.getTempid();
    }

    /**
     * 返回H5 url
     *
     * @return url
     */
    private String getSiteUrl() {
        String apiUrl = redisUtils.getY(ShopKeyUtils.getSiteUrl());
        if (StrUtil.isBlank(apiUrl)) {
            return "";
        }
        return apiUrl;
    }

    /**
     * 获取openid
     *
     * @param uid uid
     * @return String
     */
    private String getUserOpenid(Long uid) {
        YxUser yxUser = userService.getById(uid);
        if (yxUser == null) {
            return "";
        }

        WechatUserDto wechatUserDto = yxUser.getWxProfile();
        if (wechatUserDto == null) {
            return "";
        }
        if (StrUtil.isBlank(wechatUserDto.getOpenid())) {
            return "";
        }
        return wechatUserDto.getOpenid();

    }


}
